from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from django.conf import settings


class FastDFSStorage(Storage):
    """自定义文件存储系统 实现文件存储转存到fdfs"""

    def __init__(self, client_conf=None, base_url=None):
        """
        构造方法
        当在存储数据时 django会自动的调用构造方法 但不会传参进来
        """
        self.client_conf = client_conf or settings.FDFS_CLIENT_CONF
        self.base_url = base_url or settings.FDFS_URL

    def open(self, name, mode='rb'):
        """
        打开文件时调用
        因为此时只有文件的上传 没有文件要打开 但是又必须实现 所以pass
        :param name:
        :param mode:
        :return:
        """
        pass

    def _save(self, name, content):
        """
        存储文件时调用的
        :param name: 要存储文件名
        :param content: 要存储的文件的对象 File类型的对象 需要调用read()读取上传的文件的内容
        :return: 保存到数据库中的FastDFS的文件名

        """

        # 创建fdfs客户端 跟tracker进行交互
        client = Fdfs_client("meiduo_mall/utils/fastdfs/client.conf")

        # 调用上传方法 根据文件的内容上传的
        ret = client.upload_by_buffer(content.read())

        # 判断上传是否成功
        if ret.get("Status") != "Upload successed.":
            raise Exception("upload file failed")

        # 返回file_id 模型类会自动的读取这个file_id 存储到模型类中的ImageField字段
        file_id = ret.get("Remote file_id")
        # {
        #     'Status': 'Upload successed.',
        #     'Group name': 'group1',
        #     'Local file name': '/home/python/Desktop/1.png',
        #     'Uploaded size': '140.00KB',
        #     'Remote file_id': 'group1/M00/00/00/wKhbhFs14T2AbTtVAAIwAxa0590723.png',
        #     'Storage IP': '192.168.91.132'
        # }

        return file_id

    def exists(self, name):
        """
        判断文件是否已经在本地存储，返回True表示文件已在本地存储 djangp不会再去存储该文件
        返回False 告诉django该文件是新的文件 请你存储 只有返回False Django才会积极的存储文件到fdfs
        FastDFS可以自行解决文件的重名问题
        所以此处返回False，告诉Django上传的都是新文件
        :param name:  文件名
        :return: False
        """
        return False

    def url(self, name):
        """
        返回文件的完整URL路径
        该方法时会提供模型类对象中的ImageField对应的属性调用的(file_id被存储在ImageFiels字段中)
        :param name: 数据库中保存的文件名
        :return: 完整的URL http://192.168.91.132:8888/group1/M00/00/00/wKhbhFs14T2AbTtVAAIwAxa0590723.png
        """
        return self.base_url + name
        # return "http://192.168.91.132:8888/" + name

        # 存储
        # client.upload_by_filename("/home/python/Desktop/1.png")
